from common.views.base_views import BaseAPIView
import datetime
from tuntun.settings import ALIYUN_OSS
import base64
import json
import time
import hmac
from rest_framework.response import Response
from rest_framework.parsers import FormParser
from sdks.aliyunsdkcore import client
from sdks.aliyunsdkcore.profile import region_provider
from sdks.aliyunsdksts.request.v20150401 import AssumeRoleRequest
import copy
from apps.storage.models import PublicFile
from tuntun.settings import ALIYUN_OSS
# Create your views here.


class RequireAliYunOSSSTSUploadTokenView(BaseAPIView):
    """ Aliyun OSS STS Token"""
    def post(self, request, *args, **kwargs):
        user = request.user
        # 构建一个 Aliyun Client, 用于发起请求
        # 构建Aliyun Client时需要设置AccessKeyId和AccessKeySevcret
        REGIONID = 'cn-beijing'
        ENDPOINT = 'sts.cn-beijing.aliyuncs.com'
        # 配置要访问的STS Endpoint
        region_provider.add_endpoint('Sts', REGIONID, ENDPOINT)
        # 初始化Client
        clt = client.AcsClient(ALIYUN_OSS['AccessKeyId'], ALIYUN_OSS['AccessKeySecret'], REGIONID)
        # 构造"AssumeRole"请求
        request = AssumeRoleRequest.AssumeRoleRequest()
        # 指定角色
        request.set_RoleArn(ALIYUN_OSS['WriterRolArn'])
        # 指定策略
        # request.set_Policy("")
        # 设置会话名称，审计服务使用此名称区分调用者
        request.set_RoleSessionName('test')
        # 发起请求，并得到response
        response = clt.do_action_with_exception(request)
        resp = json.loads(response)
        del resp['AssumedRoleUser']
        del resp['RequestId']
        resp['bucket'] = ALIYUN_OSS['bucket']
        callback_body = {
            "callbackUrl": ALIYUN_OSS['callback_url'],
            "callbackHost": ALIYUN_OSS['callback_host'],
            "callbackBody":"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}",
            "callbackBodyType":"application/x-www-form-urlencoded",
        }
        base64_callback_body = base64.b64encode(json.dumps(callback_body).encode())
        # resp['callback'] = base64_callback_body.decode()
        resp['callback_body'] = callback_body
        return Response(resp)


class RequireAliYunOSSUploadTokenView(BaseAPIView):
    """
    请求阿里云OSS上传Token
    """
    def post(self, request, *args, **kwargs):
        user = request.user
        now = datetime.datetime.now()
        expire_in = 30
        expire_at = now + datetime.timedelta(seconds=expire_in)
        access_key_id = ALIYUN_OSS['AccessKeyId']
        access_key_secret = ALIYUN_OSS['AccessKeySecret']
        host = ALIYUN_OSS['oss_endpoint']
        callback_body = {
            "callbackUrl": ALIYUN_OSS['callback_url'],
            "callbackHost": ALIYUN_OSS['callback_host'],
            "callbackBody": "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}",
            "callbackBodyType": "application/x-www-form-urlencoded",
        }
        base64_callback_body = base64.b64encode(json.dumps(callback_body).encode())
        expiration = expire_at.isoformat()+'Z'
        to_dir = '%s/%s/' % (user.id, time.strftime('%Y%m/%d%H'))
        condition = [
            ['content-length-range', 0, 1048576000],
            ['starts-with', '$key', to_dir],
        ]
        policy = {
            'expiration': expiration,
            'conditions': condition,
        }
        base64_policy = base64.b64encode(json.dumps(policy).encode())
        signature = base64.b64encode(hmac.new(access_key_secret.encode(), base64_policy, 'sha1').digest())
        data = {
            'accessid': access_key_id,
            'host': host,
            'policy': base64_policy.decode(),
            'signature': signature.decode(),
            'expire': now.timestamp() + expire_in,
            'callback': base64_callback_body.decode(),
            'dir':  to_dir,
        }
        self.resp['params'] = data
        return Response(self.resp)


class AliYunOSSSTSUploadCallbackView(BaseAPIView):
    permission_classes = ()
    def post(self, request, *args, **kwargs):
        data = copy.copy(request.data)
        filename = data.get('filename')
        size = data.get('size')
        mimeType = data.get('mimeType')
        height = data.get('height')
        width = data.get('width')
        meta_data = {'filename': filename, 'size': size, 'mimeType': mimeType, 'height': height, 'width': width}
        public_file = PublicFile.objects.create(name=filename,
                                                meta_data=meta_data,
                                                mime_type=mimeType,
                                                url=ALIYUN_OSS['oss_endpoint']+'/'+filename)
        print(public_file.as_dict())
        return Response(public_file.as_dict())
